package com.spudtech.collision.polygon
{
    
    import flash.geom.*;
    
    
    public class SpudVector extends Point
    {
        
        public function SpudVector(init_x : Number, init_y : Number)
        {
            super(init_x,init_y);
        }
        
        public static function copyVector(to_copy : *) : SpudVector
        {
            if (to_copy is Point)
            {
                // It is either a flash.geom.Point
                // or a SpudVector
                // Well, either way it's a
                // flash.geom.Point
                
                return new SpudVector(to_copy.x, to_copy.y);
                
            }
            else if (to_copy is Array)
            {
                // If it has 2 members and both are
                // Number's then we can use it
                
                if (to_copy.length == 2)
                {
                    if (to_copy[0] is Number &&
                        to_copy[1] is Number)
                    {
                        return new SpudVector(to_copy[0],to_copy[1]);
                    }
                    else
                    {
                        throw new TypeError("Invalid Array given (Both elements must be Numbers)");
                    }
                }
                else
                {
                    throw new TypeError("Invalid Array given (Must have exactly 2 members)");
                }
                
            }
            else
            {
                // Whatever it is, we can't use it
                
                throw new TypeError("Invalid vector given (what is this i dont even)");
                
            }
            
        }
        
        
        public static function fromRect(init_x : Number, init_y : Number) : SpudVector
        {
            var new_vec : SpudVector = new SpudVector(1,1);
            
            new_vec.x = init_x;
            new_vec.y = init_y;
            
            return new_vec;
            
        }
        public static function fromPolar(init_r : Number, init_theta : Number) : SpudVector
        {
            var new_vec : SpudVector = new SpudVector(1,1);
            
            new_vec.r = init_r;
            new_vec.angle = init_theta;
            
            return new_vec;
            
        }
        
        
        override public function clone() : Point
        {
            return new SpudVector(this.x,this.y);
        }
        
        public function cloneVec() : SpudVector
        {
            // clone() returns a SpudVector
            // as a flash.geom.Point so we
            // can just cast it
            return SpudVector(this.clone());
        }
        
        
        public function set length(new_length : Number) : void
        {
            // Take the caller's normal
            // Multiply is by the new length
            var new_vec : SpudVector = this.normal.mul(new_length);
            
            this.x = new_vec.x;
            this.y = new_vec.y;
            
        }
        
        public function get angle() : Number
        {
            return Math.atan2(this.y,this.y) * (180.0 / Math.PI);
        }
        public function set angle(new_angle : Number) : void
        {
            var len : Number = this.length;
            
            // In both, we convert the new angle
            // into radians
            this.x = len * Math.cos(new_angle*(Math.PI / 180.0));
            this.y = len * Math.sin(new_angle*(Math.PI / 180.0));
            
        }
        
        
        public function get r() : Number
        {
            // Alias for 'length'
            return length
        }
        public function set r(new_r : Number) : void
        {
            // Alias for 'length'
            length = new_r;
        }
        
        public function get theta() : Number
        {
            // Alias for 'angle'
            return angle;
        }
        public function set theta(new_theta : Number) : void
        {
            angle = new_theta;
        }
        
        
        public function get inverse() : SpudVector
        {
            return new SpudVector((this.x * -1),(this.y * -1));
        }
        public function get horizontalInverse() : SpudVector
        {
            return new SpudVector((this.x * -1),this.y);
        }
        public function get verticalInverse() : SpudVector
        {
            return new SpudVector(this.x,(this.y * -1));
        }
        
        
        public function get normal() : SpudVector
        {
            return div(this.length);
        }
        
        
        public function sub(to_sub : SpudVector) : SpudVector
        {
            return copyVector(add(to_sub.inverse));
        }
        
        public function mul(factor : Number) : SpudVector
        {
            return new SpudVector(this.x * factor,this.y * factor);
        }
        public function div(divisor : Number) : SpudVector
        {
            return mul(1.0 / divisor);
        }
        
    }
    
}
